import axios from 'axios'
import { showError } from '@/libs/messages'
import { isGotoLogin, gotoLogin, checkAccess, isAccessDeny, showDenyPage } from '@/libs/runjson'
import store from '@/store'

let errorGenerate = (error) => {
  return '<div>{0}</div>'.format(error)
}

if (process.env.NODE_ENV === 'development') {
  errorGenerate = (error, index, service) => {
    return '<div>{2}.{0}:{1}</div>'.format(index, error, service)
  }
}

class AxiosInstance {
  /**
   * 下载文件
   * @param {Object} data
   * @param {*} cancelHandle
   * @param {Object} extOpt 其它 header 属性
   */
  download(data, extOpt, cancelHandle) {
    const opt = Object.assign({
      method: 'get',
      responseType: 'blob',
      data
    }, extOpt)
    if (cancelHandle) {
      opt['cancelToken'] = new axios.CancelToken(function executor(c) {
        cancelHandle(c)
      })
    }
    return this.service(opt)
  }

  /**
   * @param {*} opt  请求信息
   * @param {*} autoProcessRJError 是否自动提示错误信息
   */
  request(opt, autoProcessRJError) {
    return new Promise((resolve, reject) => {
      this.service(opt).then(res => {
        // 判断返回的是否是 json 对象
        if (!(res instanceof Object)) {
          // 如果不是 Object ，则 reject
          reject(res)
          return
        }
        // console.log(res)
        // 获取数据
        const { error, data } = res
        // 权限判断
        if (isAccessDeny(error)) {
          // 没有权限
          showDenyPage(this.page)
          // showError('没有操作权限')
          reject(res)
          return
        }
        // 自动处理错误，并剥离数据
        if (autoProcessRJError === undefined || autoProcessRJError) {
          // 其他错误
          if (error) {
            // 自动处理错误
            showError(error)
            reject(error)
            return
          }
          // 自动处理错误
          let gotAccessDeny = false
          let firstResultData = null
          let firstError = null
          let resultCount = 0
          const errors = []
          // 处理各个请求的内部错误信息
          for (var svc in data) {
            const result = data[svc]
            resultCount++
            const { error } = result
            const bData = result.data
            if (!firstResultData) { // 记录第一个返回值
              firstResultData = bData
            }
            if (isAccessDeny(error) && !gotAccessDeny) {
              gotAccessDeny = true
            }

            if (error) {
              if (!firstError) {
                firstError = error
              }
              // errors.push('{0}.{1}'.format(index, error))
              errors.push(errorGenerate(error, 0, svc))
            }
          }

          // errors.length > 0 时表示有错误发生
          if (errors.length > 0) {
            if (gotAccessDeny) {
              // 处理没有权限的问题
              showDenyPage(this.page)
              // showError('没有操作权限')
            }
            if (resultCount > 1) {
              const msg = errors.join('')
              showError(msg, true)
            } else {
              showError(firstError)
            }
            // 自动处理错误的情况下，发生错误时，也将调用 resolve ，参数为空
            return resolve()
          }
          // console.log('resultCount', resultCount, 'firstResultData', firstResultData)
          if (resultCount > 1) {
            // 多条返回信息
            return resolve(data)
          } else { // if (firstResultData !== null && firstResultData !== undefined) {
            // 有单条反馈数据，返回数据
            return resolve(firstResultData)
          }
          // else {
          //   return reject('数据错误')
          // }
        } else {
          // 所有操作交由调用者处理
          if (error) {
            return reject(error)
          }
          // console.log('111', data)
          const keys = Object.keys(data)
          // console.log('keys', keys)
          if (keys.length === 1) {
            const r = data[keys[0]]
            return resolve(r)
          }
          // console.log('res', data)
          return resolve(data)
        }
      }).catch(err => {
        reject(err)
      })
    })
  }

  // error(message, html) {
  //   Message({
  //     message: message,
  //     dangerouslyUseHTMLString: html,
  //     type: 'error',
  //     duration: 5 * 1000
  //   })
  // }
  page = null

  constructor(page) {
    this.page = page
    this.service = axios.create({
      url: process.env.API_URL,
      // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
      // withCredentials: true, // send cookies when cross-domain requests
      timeout: 30000 // request timeout
    })
    this.interceptors(this.service, page)
  }

  interceptors(service, page) {
    service.interceptors.request.use(cfg => {
      // 如果需要使用自定义头，请在这里配置
      // console.log('store.getters.token', store.getters.token)
      // console.log('getTokenKey()', getTokenKey())
      // console.log('getToken()', getToken())
      // // if (store.getters.token) {
      //   cfg.headers[store.getters.key] = store.getters.token
      //   cfg.headers[getTokenKey()] = getToken()
      // // }
      return cfg
    }, err => {
      // console.log(err) // for debug
      return Promise.reject(err)
    })

    // 添加反馈拦截器
    service.interceptors.response.use(res => {
      // 判断返回的是否是 json 对象
      if (!(res instanceof Object)) {
        // 如果不是 Object，交给后续处理，拦截器中不做任何处理
        Promise.resolve(res)
        return
      }
      // 从返回信息中，获取 data
      // console.log('res', res)
      const { data } = res
      if (!data) {
        Promise.resolve(res)
        return
      }
      this.processExtra(data)
      const { error } = data
      // 判断是否需要登录，需要重新登录的错误，只出现在最顶层
      if (error) {
        // 发生错误
        // 判断错误类型
        if (isGotoLogin(error)) {
          // 需要登录 to re-login
          gotoLogin()
          return Promise.resolve()
        } else {
          checkAccess(data, page)
        }
      }
      // if (isGotoLogin(error)) {
      //   gotoLogin()
      //   return Promise.resolve()
      // }
      return data
    }, err => {
      // 发生错误
      if (!axios.isCancel(err)) {
        // 不是取消操作, 提示错误信息
        showError(err.message || 'error: 没有错误信息')
      }
      Promise.reject(err)
    })
  }

  processExtra(responseData) {
    if (!responseData) {
      return
    }
    const { extra } = responseData
    // console.log('extra', extra)
    if (extra) {
      // const { tag, data } = data['extra']
      // 检查是否返回 token
      const token = extra[store.getters.updateTokenExtra]
      if (token) {
        // 更新本地 token
        // console.log('new token', token)
        store.commit('user/SET_TOKEN', token)
      }

      const messageCount = extra[store.getters.messageCountExtra]
      if (messageCount) {
        // 更新消息数量
        store.commit('user/SET_MESSAGE', messageCount)
      }
    }
  }
  // processExtraData(data) {
  //   // 处理额外数据，如 token 更换，消息等
  //   const { extra } = data
  //   if (extra) {
  //     console.log('extra', extra)
  //     const token = extra['ta-token-update']
  //     if (token) {
  //       // 如果有 token ，则说明需要更新
  //       store.dispatch('user/updateToken', token)
  //     }
  //     const messageCount = extra['ta-message-count-update']
  //     if (messageCount) {
  //       // 更新消息数量
  //       store.dispatch('user/updateMessage', messageCount)
  //     }
  //   }
  // }
}

export default AxiosInstance
